package mark

import (
	"bytes"
	"encoding/base64"
	"errors"
	"github.com/golang/glog"
	"image"
	"image/draw"
	"image/jpeg"
	"image/png"
	"io"
)

const (
	SignTypePng = iota
	SignTypeJpg
)

type Mark struct {
	startPoint image.Point
}

func NewMark() *Mark {
	return &Mark{
		startPoint: image.ZP,
	}
}

func (this *Mark) Mark(input io.Reader, logo io.Reader, output io.Writer, format int) error {
	var (
		origin    image.Image
		watermark image.Image
		err       error
	)
	switch format {
	case SignTypePng:
		origin, err = png.Decode(input)
	case SignTypeJpg:
		origin, err = jpeg.Decode(input)
	default:
		err = errors.New("not support format, now support png,jpeg")
	}
	if err != nil {
		glog.Errorf("image decode error(%v)", err)
		return err
	}
	switch format {
	case SignTypePng:
		watermark, err = png.Decode(logo)
	case SignTypeJpg:
		watermark, err = jpeg.Decode(logo)
	default:
		err = errors.New("not support format, now support png,jpeg")
	}
	if err != nil {
		glog.Errorf("image decode error(%v)", err)
		return err
	}
	dst := WaterMarkImage(origin, watermark)
	switch format {
	case SignTypePng:
		err = png.Encode(output, dst)
	case SignTypeJpg:
		err = jpeg.Encode(output, dst, nil)
	default:
		err = errors.New("not support format, now support png,jpeg")
	}
	if err != nil {
		glog.Errorf("image encode error(%v)", err)
		return err
	}
	return nil
}

func (this *Mark) MarkOutBase64(input io.Reader, logo io.Reader, output io.Writer, format int) error {
	var (
		origin    image.Image
		watermark image.Image
		err       error
	)
	switch format {
	case SignTypePng:
		origin, err = png.Decode(input)
	case SignTypeJpg:
		origin, err = jpeg.Decode(input)
	default:
		err = errors.New("not support format, now support png,jpeg")
	}
	if err != nil {
		glog.Errorf("image decode error(%v)", err)
		return err
	}
	switch format {
	case SignTypePng:
		watermark, err = png.Decode(logo)
	case SignTypeJpg:
		watermark, err = jpeg.Decode(logo)
	default:
		err = errors.New("not support format, now support png,jpeg")
	}
	if err != nil {
		glog.Errorf("image decode error(%v)", err)
		return err
	}
	dst := WaterMarkImage(origin, watermark)
	emptyBuff := bytes.NewBuffer(nil) //开辟一个新的空buff
	switch format {
	case SignTypePng:
		err = png.Encode(emptyBuff, dst)
	case SignTypeJpg:
		err = jpeg.Encode(emptyBuff, dst, nil)
	default:
		err = errors.New("not support format, now support png,jpeg")
	}
	if err != nil {
		glog.Errorf("image encode error(%v)", err)
		return err
	}
	base64pic := base64.StdEncoding.EncodeToString(emptyBuff.Bytes())
	output.Write([]byte(base64pic))
	return nil
}

func WaterMarkImage(img image.Image, watermark image.Image) image.Image {
	//把水印写到右下角，并向0坐标各偏移10个像素
	//offset := image.Pt(img.Bounds().Dx()-watermark.Bounds().Dx()-10, img.Bounds().Dy()-watermark.Bounds().Dy()-10)
	offset := image.Pt(img.Bounds().Dx()-watermark.Bounds().Dx(), img.Bounds().Dy()-watermark.Bounds().Dy())
	b := img.Bounds()
	newImg := image.NewNRGBA(b)
	draw.Draw(newImg, b, img, image.ZP, draw.Src)
	draw.Draw(newImg, watermark.Bounds().Add(offset), watermark, image.ZP, draw.Over)
	return newImg
}
